package zkdemo;

import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.AsyncCallback.Children2Callback;
import org.apache.zookeeper.AsyncCallback.StringCallback;
import org.apache.zookeeper.AsyncCallback.VoidCallback;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

public class ZKApiDemo {
	static CountDownLatch latch = new CountDownLatch(1);
	
	ZooKeeper zk;
	
	@Before
	public void init() throws Exception {
		zk = new ZooKeeper("192.168.10.188:2181", 5000, new Watcher() {
			@Override
			public void process(WatchedEvent event) {
				System.out.println("event="+event);
				if(event.getState() == KeeperState.SyncConnected) {
					latch.countDown();
				}
			}
		});
		latch.await();
	}
	
	//创建节点-同步
	@Test
	public void create_synchronous() throws Exception {
		/**
		 *  public String create(final String path, byte data[], List<ACL> acl,CreateMode createMode)
		 *  public void create(final String path, byte data[], List<ACL> acl,CreateMode createMode,  StringCallback cb, Object ctx)
		 *  
		 *  path:
		 *  	节点路径
		 *  data:
		 *  	节点初始内容
		 *  acl:
		 *		节点ACL策略
		 *	createMode:
		 *		节点类型 PERSISTENT(持久) PERSISTENT_SEQUENTIAL(持久有序) EPHEMERAL(临时) EPHEMERAL_SEQUENTIAL(临时有序)
		 *	cb:
		 *		节点创建成功回调
		 *	ctx:
		 *		回调执行时候使用，通常是上下文信息	
		 */
		String path = zk.create("/zk-book/path1" , 
				"".getBytes() , 
				Ids.OPEN_ACL_UNSAFE , 
				CreateMode.PERSISTENT);
		
		System.out.println("ok path:"+path);
		
		path = zk.create("/zk-book/path2" , 
				"".getBytes() , 
				Ids.OPEN_ACL_UNSAFE , 
				CreateMode.PERSISTENT_SEQUENTIAL);
		
		System.out.println("ok path:"+path);
	}
	
	//创建节点-异步
	@Test
	public void create_asynchronous() throws Exception {
		zk.create("/zk-book/path3" , 
			"".getBytes() , 
			Ids.OPEN_ACL_UNSAFE , 
			CreateMode.PERSISTENT,new StringCallback() {
				/**
				 * rc: 
				 * 	0 		成功
				 *  -4		客户端和服务端链接已断开
				 *  -110	指定节点已经存在
				 *  -112	会话已经过期
				 * path:
				 * 	接口调用传入的path
				 * ctx:
				 * 	接口调用传入的ctx
				 * name:
				 * 	实际在服务器创建的节点名称
				 */
				public void processResult(int rc, String path, Object ctx, String name) {
					System.out.println("ok rc="+rc+" path="+path+" ctx="+ctx+" name="+name);
				}
			},"I am a context");
		
		Thread.sleep(Long.MAX_VALUE);
	}
	//删除节点-同步
	@Test
	public void del_synchronous() throws Exception {
		zk.delete("/zk-book", -1);
	}
	//删除节点-异步
	@Test
	public void del_asynchronous() throws Exception {
		zk.delete("/zk-book", -1, new VoidCallback() {
			public void processResult(int rc, String path, Object ctx) {
				System.out.println("ok rc="+rc+" path="+path+" ctx="+ctx);
			}
		}, "I am a context");
		Thread.sleep(Long.MAX_VALUE);
	}
	//获取节点数据-同步
	@Test
	public void get_synchronous() throws Exception {
		List<String> childrenList = zk.getChildren("/zk-book", true);
		System.out.println("childrenList="+childrenList);
		zk.create("/zk-book/path4" , 
				"".getBytes() , 
				Ids.OPEN_ACL_UNSAFE , 
				CreateMode.PERSISTENT);
	}
	//获取节点数据-异步
	@Test
	public void get_asynchronous() throws Exception {
		zk.getChildren("/zk-book", true, new Children2Callback() {
			public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
				System.out.println("ok rc="+rc+" path="+path+" ctx="+ctx+" children="+children+" stat="+stat);
			}
		},null);
		
		zk.create("/zk-book/path5" , 
				"".getBytes() , 
				Ids.OPEN_ACL_UNSAFE , 
				CreateMode.PERSISTENT);
	}
}
